/*
 *
 * Copyright (c) 2006-2020, Speedment, Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); You may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.speedment.runtime.core.db;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import com.speedment.runtime.core.exception.SpeedmentException;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.sql.SQLException;
import java.util.function.Function;

final class SqlFunctionTest {

    @ParameterizedTest
    @ValueSource(strings = "test")
    void wrap(String input) throws SQLException {
        assertThrows(NullPointerException.class, () -> SqlFunction.wrap(null));

        final Function<String, String> function = Function.identity();
        final SqlFunction<String, String> sqlFunction = SqlFunction.wrap(function);

        assertNotNull(sqlFunction);
        assertEquals(function.apply(input), sqlFunction.apply(input));
    }

    @ParameterizedTest
    @ValueSource(strings = "test")
    void unWrap(String input) throws SQLException {
        final SqlFunction<String, String> sqlFunction = SqlFunction.identity();
        final Function<String, String> function = sqlFunction.unWrap();

        assertNotNull(function);
        assertEquals(sqlFunction.apply(input), function.apply(input));

        final SqlFunction<String, String> throwingSqlFunction = string -> {
            throw new SQLException();
        };
        final Function<String, String> throwingFunction = throwingSqlFunction.unWrap();

        assertThrows(SpeedmentException.class, () -> throwingFunction.apply(input));
    }

    @ParameterizedTest
    @ValueSource(strings = "test")
    void identity(String input) throws SQLException {
        final SqlFunction<String, String> sqlFunction = SqlFunction.identity();

        assertEquals(input, sqlFunction.apply(input));
    }

    @ParameterizedTest
    @ValueSource(strings = "test")
    void compose(String input) throws SQLException {
        final SqlFunction<String, String> prefixFunction = x -> "prefix" + x;
        final SqlFunction<String, String> suffixFunction = x -> x + "suffix";

        assertThrows(NullPointerException.class, () -> suffixFunction.compose(null));

        final SqlFunction<String, String> composed = suffixFunction.compose(prefixFunction);

        assertEquals("prefix" + input + "suffix", composed.apply(input));
    }

    @ParameterizedTest
    @ValueSource(strings = "test")
    void andThen(String input) throws SQLException {
        final SqlFunction<String, String> prefixFunction = x -> "prefix" + x;
        final SqlFunction<String, String> suffixFunction = x -> x + "suffix";

        assertThrows(NullPointerException.class, () -> suffixFunction.andThen(null));

        final SqlFunction<String, String> combined = prefixFunction.andThen(suffixFunction);

        assertEquals("prefix" + input + "suffix", combined.apply(input));
    }
}
